﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace ExpressionStudy
{
    class Program
    {
        static void Main(string[] args)
        {
            //修改表达式树

            //Expression<Func<string, bool>> expr = name => name.Length > 10 && name.StartsWith("G");
            //Console.WriteLine(expr);

            //AndAlsoModifier treeModifier = new AndAlsoModifier();
            //Expression modifiedExpr = treeModifier.Modify((Expression)expr);

            //Console.WriteLine(modifiedExpr);
            //Console.ReadKey();

            //动态生成Linq查询
            string[] companies = { "Consolidated Messenger", "Alpine Ski House", "Southridge Video", "City Power & Light",
                               "Coho Winery", "Wide World Importers", "Graphic Design Institute", "Adventure Works",
                               "Humongous Insurance", "Woodgrove Bank", "Margie's Travel", "Northwind Traders",
                               "Blue Yonder Airlines", "Trey Research", "The Phone Company",
                               "Wingtip Toys", "Lucerne Publishing", "Fourth Coffee" };

            // The IQueryable data to query.
            IQueryable<String> queryableData = companies.AsQueryable<string>();

            // Where(company => (company.ToLower() == "coho winery" || company.Length > 16))
            var company = Expression.Parameter(typeof(string), "company");

            Expression left = Expression.Call(company, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
            Expression right = Expression.Constant("coho winery");

            Expression body = Expression.Equal(left, right);


            left = Expression.Property(company, "Length");
            right = Expression.Constant(16);


            Expression body2 = Expression.GreaterThan(left, right);

            Expression predicateBody = Expression.OrElse(body, body2);


            MethodCallExpression whereCallExpression = Expression.Call(typeof(Queryable), "Where", new Type[] { queryableData.ElementType }, queryableData.Expression,
            Expression.Lambda<Func<string, bool>>(predicateBody, new ParameterExpression[] { company }));

            MethodCallExpression orderByCallExpression = Expression.Call(
              typeof(Queryable),
              "OrderBy",
              new Type[] { queryableData.ElementType, queryableData.ElementType },
              whereCallExpression,
              Expression.Lambda<Func<string, string>>(company, new ParameterExpression[] { company }));
            IQueryable<string> results = queryableData.Provider.CreateQuery<string>(orderByCallExpression);
            foreach (string i in results)
                Console.WriteLine(i);
        }




    }

}
